const path = require('path');
const chalk = require('chalk');
const download = require('download');
const fs = require('fs-extra');
const glob = require('glob');
const parseArgs = require('yargs-parser');

const gitGroup = process.env.BUILD_GIT_GROUP || '';
const gitProject = process.env.BUILD_GIT_PROJECT || '';
const gitBranch = process.env.BUILD_GIT_BRANCH || '';
const gitBranchParts = gitBranch.split('/');
const assetsVersion = gitBranchParts[gitBranchParts.length - 1];
const buildArgv = parseArgs(process.env.BUILD_ARGV_STR || '') || {};
const defOriginBranch = buildArgv.def_publish_devbranches;

console.log('====DEF 源分支====', defOriginBranch);

// release/x.x.x 分支才做本地化
if (defOriginBranch && !defOriginBranch.startsWith('release/')) {
  return; // eslint-disable-line
}

const { outputPrefix: publicOutputPrefix, version } = fs.readJSONSync(
  path.resolve(__dirname, '../env.json'),
);

let outputPrefix; // 环境里的资源路径
if (process.env.BUILD_ENV !== 'cloud') {
  outputPrefix = `${publicOutputPrefix}${version}/`;
} else {
  outputPrefix = `${publicOutputPrefix}${gitGroup}/${gitProject}/${assetsVersion}/`;
}

const srcDir = path.join(__dirname, '../build/');
const destDir = path.join(__dirname, '../vpc/');
const destDownloadDir = path.join(destDir, 'downloads/');

fs.emptyDirSync(destDir);
fs.copySync(srcDir, destDir, { overwrite: true });

const endsWith = (string, suffix) => {
  return string.indexOf(suffix, string.length - suffix.length) !== -1;
};
const getDownloadFileName = (url) => {
  const prefixRegex = /(https?:)?\/\/((at|img|g|gw)\.alicdn\.com)\//g;
  const urlWithoutPrefix = url.replace(prefixRegex, '');
  let fileName = urlWithoutPrefix.replace(/\//g, '_');
  if (endsWith(fileName, 'eot?#iefix')) {
    fileName = `iefix_${fileName.substring(0, fileName.length - 7)}`;
  } else if (endsWith(fileName, 'svg#iconfont')) {
    fileName = `iconfont_${fileName.substring(0, fileName.length - 9)}`;
  }
  return fileName;
};
const getDownloadFilePath = (url) => {
  const fileName = getDownloadFileName(url);
  const result = `${outputPrefix}downloads/${fileName}`;
  return result;
};
const downloadFile = async (url) => {
  const rawUrl = /^http/.test(url) ? url : `https:${url}`;
  const fileName = getDownloadFileName(url);
  try {
    await download(rawUrl, destDownloadDir, {
      filename: fileName,
    });
    console.log(chalk.green(`Download ${url} successfully`));
    return `${destDownloadDir}${fileName}`;
  } catch (err) {
    console.error(err);
  }
};

function doLocalization(filepaths) {
  let urls = [];

  filepaths.forEach((filepath) => {
    // 忽略这些后缀的文件，不需要对html内资源做下载，图片可能被损坏
    const ignoreSuffix = /\.(html|mp4|png|jpg|gif|eot|svg|ttf|woff)$/;
    if (!filepath || ignoreSuffix.test(filepath)) {
      return;
    }

    let content = fs.readFileSync(`${filepath}`, 'utf-8');

    const regexp =
      '/(https?:)?\\/\\/((at|img|g|gw)\\.alicdn\\.com).{0,500}?(js|css|mp4|png|jpg|eot(\\?#iefix)?|woff2|woff|ttf|gif|.svg(#iconfont)?)/g';
    const flags = regexp.replace(/.*\/([gimy]*)$/, '$1');
    const pattern = regexp.replace(new RegExp(`^/(.*?)/${flags}$`), '$1');
    const regex = new RegExp(pattern, flags);

    let chunkUrl = content.match(regex) || [];
    chunkUrl = chunkUrl.filter((url) => !url.includes('"') && !url.includes(process.env.CDN_PATH));
    urls = Array.from(new Set(urls.concat(chunkUrl)));

    chunkUrl.length > 0 && console.log(filepath, chunkUrl);

    chunkUrl.forEach((url) => {
      let pos = content.indexOf(url, 0);
      const downloadFilePath = getDownloadFilePath(url);
      while (pos > -1) {
        content[pos - 1] === '"' ||
        content[pos - 1] === "'" ||
        content[pos - 1] === '`' ||
        content[pos - 1] === '('
          ? (content = content.replace(url, downloadFilePath))
          : (content = content.replace(url, `\`${downloadFilePath}\``));
        pos = content.indexOf(url, pos + 1);
      }
    });

    // 替换 process.env.CDN_PATH（会被def插件写成cdn）为 本地化路径
    if (process.env.CDN_PATH) {
      content = content.replace(new RegExp(process.env.CDN_PATH, 'g'), outputPrefix);
    }

    /** 业务特殊替换逻辑 */
    // monaco-editor外链
    content = content.replace(/\/\/g.alicdn.com\/code\/lib\/monaco-editor\/0.33.0\/min\/vs/g, '/codeup/public/lib/monaco-editor/0.33.0/min/vs');
    // 插件bug，临时换为cdn
    content = content.replace(/\/codeup\/public\/5.0.0\/downloads\/code_lib_require.js\/2.3.6\/require.js/g, "//g.alicdn.com/code/lib/require.js/2.3.6/require.js");
    content = content.replace(/\/codeup\/public\/ais-fed\/code-assets\/5.0.0\/downloads\/code_lib_require.js\/2.3.6\/require.js/g, "//g.alicdn.com/code/lib/require.js/2.3.6/require.js");

    fs.writeFileSync(filepath, content, 'utf-8');
  });

  console.log('====外链数量===', urls.length);
  // 如果下载的资源中外链数量不为0，则递归，否则结束递归
  if (urls.length === 0) {
    // 清空build/目录，然后将 vpc/ 移至 build/ 目录，以发布
    fs.emptyDirSync(srcDir);
    fs.copySync(destDir, srcDir, { overwrite: true });
    // fs.removeSync(destDir, { recursive: true, force: true }); // 需要node-14

    console.log('====资源本地化完毕=====');
  } else {
    Promise.allSettled(urls.map((url) => downloadFile(url))).then(
      (downloadedFiles) => {
        // 递归
        doLocalization(downloadedFiles.map(({ value }) => value));
      },
    );
  }
}

doLocalization(glob.sync(`${destDir}**/*.*`));
